package io.hellsinger.vortex.ui.component

import android.content.Context
import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.TypedValue
import android.util.TypedValue.COMPLEX_UNIT_DIP
import android.util.TypedValue.COMPLEX_UNIT_SP
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.roundToInt

inline fun <reified T : Number> DisplayMetrics.applyDimension(
    unit: Int,
    value: T,
): T = TypedValue.applyDimension(unit, value.toFloat(), this) as T

inline fun <reified T : Number> DisplayMetrics.dp(value: T): T = applyDimension(COMPLEX_UNIT_DIP, value)

inline fun <reified T : Number> DisplayMetrics.sp(value: T): T = applyDimension(COMPLEX_UNIT_SP, value)

inline fun <reified T : Number> Resources.dp(size: T): T = displayMetrics.dp(size)

inline fun <reified T : Number> Resources.sp(size: T): T = displayMetrics.sp(size)

inline fun <reified T : Number> Context.dp(size: T): T = resources.dp(size)

inline fun <reified T : Number> Context.sp(size: T): T = resources.sp(size)

inline fun <reified T : Number> View.dp(size: T): T = resources.dp(size)

inline fun <reified T : Number> View.sp(size: T): T = resources.sp(size)

context(View)
inline val Int.dp: Int
    get() = dp(toFloat()).roundToInt()

context(View)
inline val Float.dp: Float
    get() = dp(this)

context(View)
inline val Int.sp: Int
    get() = sp(toFloat()).roundToInt()

context(View)
inline val Float.sp: Float
    get() = sp(this)

fun View.observeInsets(listener: View.OnApplyWindowInsetsListener) {
    setOnApplyWindowInsetsListener(listener)

    if (isAttachedToWindow) {
        requestApplyInsets()
    } else {
        addOnAttachStateChangeListener(
            object : View.OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(v: View) {
                    v.removeOnAttachStateChangeListener(this)
                    v.requestApplyInsets()
                }

                override fun onViewDetachedFromWindow(v: View) = Unit
            },
        )
    }
}

inline fun RecyclerView.linear(block: LinearLayoutManager.() -> Unit) {
    val manager = layoutManager ?: return
    if (manager !is LinearLayoutManager) return

    block(manager)
}
